/**
 * 
 */
package at.ac.lbg.media.vis.framework.service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import no.uib.cipr.matrix.Matrix;
import no.uib.cipr.matrix.NotConvergedException;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import at.ac.lbg.media.vis.framework.domain.ArtworkDO;
import at.ac.lbg.media.vis.framework.domain.ArtworkDetailsDO;
import at.ac.lbg.media.vis.framework.domain.CategoryDO;
import at.ac.lbg.media.vis.framework.model.Artwork;
import at.ac.lbg.media.vis.framework.model.ArtworkDetails;
import at.ac.lbg.media.vis.framework.model.Category;
import at.ac.lbg.media.vis.framework.model.ThemeLandscapeHexboardDataItem;

/**
 * Facade for the VisuFramework for the themelandscape
 * @author Evelyn Münster
 *
 */
public class ThemeService implements IThemeService {
	private IArtworkService artworkService;
	private IMDSService mdsService;
	private IHexboardService hexboardService;
	private ICategoryService categoryService;
	// local data cache
	private Map<Integer, List<Artwork>> artworkCache = new HashMap<Integer, List<Artwork>>();
	private List<Artwork> overviewCache;
	
	protected final Log logger = LogFactory.getLog(getClass());
	//also change in TaxoVisClient.mxml
	public static final Boolean useHexBoard = true;
	
	

	@Override
	public List<Artwork> getArtworks(int sectionId) throws NotConvergedException, Exception {
		logger.debug("serving ThemeService#getArtworks(sectionID=" + sectionId + "). ");
		if (artworkCache.containsKey(sectionId)) {
			return artworkCache.get(sectionId);
		}
		List<ArtworkDO> artworkDOs = artworkService.getAllArtworks(sectionId);
		List<CategoryDO> categoryStructure = categoryService.getCategoryStructure(sectionId);
		// extract all keywords and drop the categories for mds
		List<CategoryDO> keywords = new ArrayList<CategoryDO>();
		for (CategoryDO cat : categoryStructure) {
		    keywords.addAll(cat.getChildren());
		}
		
		List<Artwork> artworks = new ArrayList<Artwork>();		
		
		
		if (useHexBoard) {
			artworkService.copyValues(artworks, artworkDOs);
			hexboardService.setDimenions(categoryService.getKeywords().size());
			List<ThemeLandscapeHexboardDataItem> hexCoordinates = hexboardService.provideCoordinates(artworks);
			artworkService.copyCoordinates(artworks, hexCoordinates);
		} else {
			Matrix coordinates = mdsService.provideCoordinates(artworkDOs, keywords);
			artworkService.copyValues(artworks, artworkDOs, coordinates);
		}
		
		artworkCache.put(sectionId, artworks);
		
		return artworks;
	}
	
   @Override
    public List<Artwork> getAllArtworks(List<Object> selectedCategories) throws NotConvergedException, Exception {

        List<ArtworkDO> artworkDOs = artworkService.getAllArtworks();
        List<CategoryDO> cats = categoryService.convertToCategories(selectedCategories);
       // Matrix coordinates = mdsService.provideCoordinates(artworkDOs, cats);
        List<Artwork> artworks = new ArrayList<Artwork>();
       // artworkService.copyValues(artworks, artworkDOs, coordinates);

        if (useHexBoard) {
        	artworkService.copyValues(artworks, artworkDOs);
        	hexboardService.setDimenions(categoryService.getKeywords().size());
        	//req hexboard coordinates
			List<ThemeLandscapeHexboardDataItem> hexCoordinates = hexboardService.provideCoordinates(artworks);
			artworkService.copyCoordinates(artworks, hexCoordinates);
        }else{
        	Matrix coordinates = mdsService.provideCoordinates(artworkDOs, cats);
			artworkService.copyValues(artworks, artworkDOs, coordinates);
        }
        
        logger.debug("serving artworks " + artworks.size());
        return artworks;
    }
	

    @Override
    public List<Artwork> getAllArtworks() throws NotConvergedException, Exception {
 	   	if (overviewCache != null) {
		   return overviewCache;
 	   	}
        logger.debug("serving ThemeService#getAllArtworks.");
        List<ArtworkDO> artworkDOs = artworkService.getAllArtworks();
       // Matrix coordinates = mdsService.provideCoordinates(artworkDOs);
        List<Artwork> artworks = new ArrayList<Artwork>();
       // artworkService.copyValues(artworks, artworkDOs, coordinates);

        if (useHexBoard) {
        	artworkService.copyValues(artworks, artworkDOs);
        	hexboardService.setDimenions(categoryService.getKeywords().size());
	        //req hexboard coordinates
        	List<ThemeLandscapeHexboardDataItem> hexCoordinates = hexboardService.provideCoordinates(artworks);
        	artworkService.copyCoordinates(artworks, hexCoordinates);
        }else{
        	Matrix coordinates = mdsService.provideCoordinates(artworkDOs);
        	artworkService.copyValues(artworks, artworkDOs, coordinates);
        }

        overviewCache = artworks;
        logger.debug("serving artworks " + artworks.size());
        return artworks;
    }
    
    @Override
    public ArtworkDetails getArtworkDetails(int artworkId) {
        ArtworkDetailsDO awDO = artworkService.getArtworkDetails(artworkId);
        ArtworkDetails awd = new ArtworkDetails();
        artworkService.copyValues(awd, awDO);
        return awd;
    }
	
	@Override
	public List<Category> getCategoryStructure() {
		logger.debug("serving ThemeService#getCategoryStructure.");
		List<Category> structure = categoryService.translate(categoryService.getCategoryStructure());
		logger.debug("serving main " + structure.size());
		return structure;
	}
	
   @Override
    public List<Category> getCategoryStructure(int sectionId) {
        logger.debug("serving ThemeService#getCategoryStructure(" + sectionId + ").");
        List<Category> structure = categoryService.translate(categoryService.getCategoryStructure(sectionId));
        logger.debug("serving section structure, size: " + structure.size());
        return structure;
    }
	
	@Override
    public List<Category> getSections() {
        logger.debug("serving ThemeService#getSections.");
        List<Category> structure = categoryService.translate(categoryService.getSections());
        logger.debug("serving sections, count:" + structure.size());
        return structure;
    }
	
	@Override
	public List<Category> getKeywords() {
		List<CategoryDO> categoryDOs = categoryService.getKeywords();
		List<Category> categories = new ArrayList<Category>();
		// copy values from CategoryDO to Category
		for (int i = 0; i < categoryDOs.size(); i++) {
			CategoryDO catDO = categoryDOs.get(i);
			Category c = categoryService.translate(catDO);
			categories.add(c);
		}
		
		return categories;
	}
	

	/**
	 * Dependency Injection
	 * @param artworkService
	 */
	public void setArtworkService(ArtworkService artworkService) {
		this.artworkService = artworkService;
	}

	/**
	 * Dependency Injection
	 * @param mdsService
	 */
	public void setMdsService(MDSService mdsService) {
		this.mdsService = mdsService;
	}
	
	/**
	 * Dependency Injection
	 * @param categoryService
	 */
	public void setCategoryService(CategoryService categoryService) {
		this.categoryService = categoryService;
	}

	/**
	 * Dependency Injection
	 * @param hexboardService
	 */
	public void setHexboardService(HexboardService hexboardService) {
		this.hexboardService = hexboardService;
	}


}
